/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package SocketCliente;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.swing.JOptionPane;

/**
 *
 * @author Santos
 */
public class JogoControl {

    /**
     * Metodo responsável por conectar-se ao servidor de socket
     *
     * @param socket
     * @throws IOException
     */
    public void connectToServer(Socket socket) throws IOException {
        //exibe informações sobre conexão
        System.out.println("Connected to: " + socket.getInetAddress().getHostName());
    }

    /**
     * Metodo responsável por obter o fluxo para enviar e receber dados
     *
     * @param model
     * @throws IOException
     */
    public void getStreams(JogoModel model) throws IOException {
        //configura o fluxo de saida para os objetos
        model.setSaida(new ObjectOutputStream(model.getClienteSocket().getOutputStream()));
        //esvazia o buffer de saida para enviar as informações de vabeçalho
        model.getSaida().flush();
        //configura o fluxo de entrada para os objetos
        model.setEntrada(new ObjectInputStream(model.getClienteSocket().getInputStream()));
        System.out.println("Estabelecida a entrada e saida de dados via socket");
    }

    /**
     * Metodo responsável por fechar a comunicação entre os socket cliente e
     * servidor
     *
     * @param model
     * @throws IOException
     */
    public void closeConnection(JogoModel model) throws IOException {
        model.getEntrada().close();
        model.getSaida().close();
        model.getClienteSocket().close();
    }

    /**
     * Retornar um numero gerado aleatoriamente
     *
     * @param model
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public String requisitarNumero(JogoModel model) throws IOException, ClassNotFoundException {
        enviarDadosServidor(model, "gerarNume");
        return processaConexaoEntrada(model);
    }

    /**
     * Metodo responsável por enviar o nome do jogador para o servidor de socket
     *
     * @param model
     * @throws IOException
     */
    public void setEnviaNomeJogador(JogoModel model) throws IOException {
        enviarDadosServidor(model, "nomeJogad" + model.getNomeJogador() + "");
    }

    /**
     * Metodo responsável por enviar o data de inicio do jogo para o servidor de
     * socket
     *
     * @param model
     * @throws IOException
     */
    public void setEnviaDataInicioJogo(JogoModel model) throws IOException {
        enviarDadosServidor(model, "dataInici" + model.getDataInicio() + "");
    }

    /**
     * Metodo responsável por enviar a hora de inicio do jogo para o servidor de
     * socket
     *
     * @param model
     * @throws IOException
     */
    public void setEnviaHoraInicioJogo(JogoModel model) throws IOException {
        enviarDadosServidor(model, "horaInici" + model.getHoraInicio() + "");
    }

    /**
     * Metodo responsável por enviar a quantidade de respostas corretas para o
     * servidor de socket
     *
     * @param model
     * @throws IOException
     */
    public void setEnviaQtdCorreta(JogoModel model) throws IOException {
        enviarDadosServidor(model, "qtdCorret" + model.getQtdCorreta() + "");
    }

    /**
     * Metodo responsável por enviar a quantidade de respostas incorretas para o
     * servidor de socket
     *
     * @param model
     * @throws IOException
     */
    public void setEnviaQtdIncorreta(JogoModel model) throws IOException {
        enviarDadosServidor(model, "qtdIncorr" + model.getQtdErrada() + "");
    }

    /**
     * Trata o retorno do servidor de socket para exibição na tela
     *
     * @param model
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public List<String> getRankingJogador(JogoModel model) throws IOException, ClassNotFoundException {
        enviarDadosServidor(model, "tamanhoLi");
        processaConexaoEntrada(model);

        enviarDadosServidor(model, "rankingJo");
        List<String> resultado = new ArrayList<>();
        for (int i = 0; i < model.getTamnhoLista() + 1; i++) {
            resultado.add(processaConexaoEntrada(model));
        }
        return resultado;
    }

    /**
     * Metodo responsável por buscar o operador a ser utilizado na equação
     *
     * @param model
     * @return numero em formato de texto
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public String requisitarOperador(JogoModel model) throws IOException, ClassNotFoundException {
        enviarDadosServidor(model, "operadorJ");
        return processaConexaoEntrada(model);
    }

    /**
     * Metodo responsável por recuperar a quantidade de respostas por jogo que
     * está definido no servidor
     *
     * @param model
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public int getQuantidadeJogadas(JogoModel model) throws IOException, ClassNotFoundException {
        enviarDadosServidor(model, "quantires");
        int numero = Integer.parseInt(processaConexaoEntrada(model));
        return numero;
    }

    /**
     * Metodo responsável por enviar para o servidor de socket quais operações o
     * usuário irá utilizar
     *
     * @param model
     * @throws IOException
     */
    public void setOperacaoSelecao(JogoModel model) throws IOException {
        enviarDadosServidor(model, "operadorS" + model.getSoma()
                + model.getSubtracao() + model.getMultiplicacao()
                + model.getDivisao() + "");
    }

    /**
     * Metodo responsável por enviar uma mensagem para o socket servidor
     *
     * @param model
     * @param message mensagem a ser transmitida
     * @throws IOException
     */
    public void enviarDadosServidor(JogoModel model, String message) throws IOException {
        model.getSaida().writeObject(message);
        model.getSaida().flush();
    }

    /**
     * Metodo responsável por receber as mensagem do servidor de socket e fazer
     * o tratamento com mensagens trabalhadas
     *
     * @param model
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public String processaConexaoEntrada(JogoModel model) throws IOException, ClassNotFoundException {
        String message = null;
        do {
            //ler uma nova mensagem
            message = (String) model.getEntrada().readObject();
            //exibir a mensagem na tela

            /**
             * Nessa etapa processo o primeiro caracter e diz o que faz
             */
            if (message.charAt(0) == '0') {
                JOptionPane.showMessageDialog(null, message.substring(1, message.length()));
                break;
            }
            //retorna mensagem para textField do numero requisitado
            if (message.charAt(0) == '1') {
                return message.substring(1, message.length());
            }
            //retorna mensagem para textField do numero requisitado
            if (message.charAt(0) == '3') {
                return message.substring(1, message.length());
            }

            //retornar os operadores que o servidor gerou aleatoriamente
            if (message.charAt(0) == '9') {
                return message.substring(1, message.length());
            }
            //verificar o tamanho da lista de resultados
            if (message.charAt(0) == '7') {
                System.out.println(message.substring(1, message.length()));
                model.setTamnhoLista(Integer.parseInt(message.substring(1, message.length())));
                break;
            }
            //exibe os resultado no final do jogo
            if (message.charAt(0) == '8') {
                return message.substring(1, message.length());
            }

        } while (!message.equals("SERVER >>> TERMINATE"));
        return message;
    }

}
